﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;

public class ABTool
{
    public static string m_BundleTargetPath = Application.streamingAssetsPath;
    public static string ABAssetsPath = "Assets/Editor/ABConfigAsset.asset";
    //key是AB 包名，Value 是路径
    public static Dictionary<string, string> _myAllFileDir = new Dictionary<string, string>();
    //用来过滤的List
    public static List<string> _myAllFileAB = new List<string>();
    //单个Prefab的 AB包
    public static Dictionary<string, List<string>> _myAllPrefabDir = new Dictionary<string, List<string>>();
    [MenuItem("Tool/AB打包")]
    public static void Build()
    {
        _myAllFileDir.Clear();
        ABAssets abssset = AssetDatabase.LoadAssetAtPath<ABAssets>(ABAssetsPath);
        foreach (ABAssets.FileDirAbName file in abssset._mAllFileDirAB)
        {
            //Debug.Log("ABName:" + file.ABName);
            //Debug.Log("ABPath:" + file.Path);

            if (_myAllFileDir.ContainsKey(file.ABName))
            {
                Debug.LogError("AB包名字重复，请注意检查");
            }
            else {
                _myAllFileDir.Add(file.ABName, file.Path);
            }
        }
        string[] allstr = AssetDatabase.FindAssets("t:Prefab", abssset._mAllPrefabPath.ToArray());
        for (int i = 0; i < allstr.Length; i++)
        {
            string path = AssetDatabase.AssetPathToGUID(allstr[i]);
            EditorUtility.DisplayProgressBar("查找Prefab", "Prefab:" + path, i * 1.0f / allstr.Length);
            if(!ContainAllFileAB(path))
            {
                GameObject obj = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                string[] allAppend = AssetDatabase.GetDependencies(path);
                List<string> alldependPath = new List<string>();
                for(int j = 0;j<allAppend.Length;j++)
                {
                    if(!ContainAllFileAB(allAppend[j])&& !allAppend[j].EndsWith(".cs"))
                    {
                        _myAllFileAB.Add(allAppend[j]);
                        alldependPath.Add(allAppend[j]);
                       
                    }
                }
                if(_myAllPrefabDir.ContainsKey(obj.name))
                {
                    Debug.Log("有相同名字的Prefab,名字：" + obj.name);
                }
                else
                {
                    _myAllPrefabDir.Add(obj.name, alldependPath);
                }
            }
        }
        foreach (string name in _myAllFileDir.Keys)
        {
            SetABName(name, _myAllFileDir[name]);
        }
        foreach (string Prename in _myAllPrefabDir.Keys)
        {
            SetABName(Prename, _myAllPrefabDir[Prename]);
        }
        string[] OldAbName = AssetDatabase.GetAllAssetBundleNames();
        for (int j = 0; j < OldAbName.Length; j++)
        {
            AssetDatabase.RemoveAssetBundleName(OldAbName[j], true);
            EditorUtility.DisplayProgressBar("清楚重复AB包", "名字:" + OldAbName[j], j * 1.0f / OldAbName.Length);
        }
        EditorUtility.ClearProgressBar();
        //foreach (string ss in abssset._mAllPrefabPath)
        //{
        //    Debug.Log("abset._mAllPrefabPath:" + ss);
        //}


        //BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath, BuildAssetBundleOptions.ChunkBasedCompression,
        //    EditorUserBuildSettings.activeBuildTarget);
        //AssetDatabase.Refresh();
    }
   
    static void SetABName(string name ,string path )
    {
        AssetImporter assetImporter = AssetImporter.GetAtPath(path);
        if(assetImporter ==null)
        {
            Debug.Log("不存在此路径:" + path);
        }
        else
        {
            assetImporter.assetBundleName= name;
        }
    }

    static void SetABName(string name,List<string> paths)
    {
        for (int i =0;i<paths.Count;i++)
        {
            SetABName(name, paths[i]);
        }
    }

    static void BuildAssetBundle()
    {
        string[] allBundles = AssetDatabase.GetAllAssetBundleNames();
        //Key为全路径 ，Value 为包名
        Dictionary<string, string> resPathDic = new Dictionary<string, string>();
        for(int i =0;i<allBundles.Length;i++)
        {
            string[] allBundlePath = AssetDatabase.GetAssetPathsFromAssetBundle(allBundles[i]);
            for (int j = 0; j < allBundlePath.Length; j++)
            {
                if (allBundles[i].EndsWith(".cs"))

                    continue;
                Debug.Log("此AB包：" + allBundles[i] + "里包含的所有文件路径：" + allBundlePath[j]);
                resPathDic.Add(allBundlePath[j], allBundles[i]);
            }
          
        }
        DeleteAB();
        //生成自己的配置表
        BuildPipeline.BuildAssetBundles(m_BundleTargetPath, BuildAssetBundleOptions.ChunkBasedCompression, 
            EditorUserBuildSettings.activeBuildTarget);
    }
    //删除多余的AB包
    static void DeleteAB()
    {
        string[] allBundlename = AssetDatabase.GetAllAssetBundleNames();
        DirectoryInfo directioninfo = new DirectoryInfo(m_BundleTargetPath);
        FileInfo[] fileinfo = directioninfo.GetFiles("*", SearchOption.AllDirectories);
        for(int i =0 ;i<fileinfo.Length;i++)
        {
            if (ContainABName(fileinfo[i].Name,allBundlename)||fileinfo[i].Name.EndsWith(".meta"))
            {
                continue;
            }
            else
            {
                Debug.Log("此AB包已经被删除或者改名字了：" + fileinfo[i].Name);
                if(File.Exists(fileinfo[i].FullName))
                {
                    File.Delete(fileinfo[i].FullName);
                }
            }
        }
    }
    static bool ContainABName( string name ,string[]strs)
    {
        for (int i =0;i<strs.Length;i++)
        {
            if(name == strs[i])
            {
                return true;
            }
        }
        return false;
    }
    static bool ContainAllFileAB (string path)
    {
        for(int i = 0;i< _myAllFileAB.Count;i++)
        {
            if(path ==_myAllFileAB[i]||path.Contains(_myAllFileAB[i]))
            {
                return true;
            }

           
        }

        return false;
    }
    /// <summary>
    /// 写入配置表
    /// </summary>
    /// <param name="resPath"></param>
   static void WriteData(Dictionary<string ,string> resPath)
    {
        ABConfigData Abcondata = new ABConfigData();
        Abcondata.Ablist = new List<ABBase>();
        foreach (string path in resPath.Keys)
        {

        }
        //写入Xml文档
        //写入二进制文档
    }
}
